﻿// screen.cpp : 定义应用程序的入口点。
//

#include "stdafx.h"
#include "screen.h"
#include <io.h>  
#include <string>  
#include <vector>
#include <atlimage.h>
#pragma comment(lib, "Msimg32.lib")
#pragma comment(lib,"Advapi32.lib")

#define TIMER_ID	1					//定时器ID
#define TIM_LONG	30000				//30S换一张图片

using namespace std;
										
INT g_nOrigin_X = -1, g_nOrigin_Y = -1;	// 保存鼠标位置

string File_Directory;					// 文件夹目录
string FileType_bmp = ".bmp";			// 需要查找的文件类型
string FileType_png = ".png";
string FileType_jpg = ".jpg"; 
string FileType_jpeg = ".jpeg";
string FileType_gif = ".gif";

vector<string>FilesName;				// 存放文件名的容器
static int index = 0;					// 遍历文件名用到的下标

//全局实例句柄
HINSTANCE g_hInst;
HWND   hwnd;

//当前要显示的图片数据参数
struct g_hBitmapStruct {
	//图片句柄
	HBITMAP bmpFile;
	//图片像素
	POINT bmpSize;
}g_hBitmapStruct;


//保存屏幕参数
int cxn = 0;
int cyn = 0;

void CALLBACK timeProc(HWND, UINT, UINT_PTR, DWORD);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int getFilesName(string &File_Directory, string &FileType, vector<string>&FilesName);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
	PSTR szCmdLine, int iCmdShow)
{
	//------------------handle argv[] param------------//
	if (__argc > 1)
	{
		//小窗预览 
		if (strstr(__argv[1], "/p"))
		{
			if (__argc == 3)
			{
				RECT rect;
				HWND hFrameWnd = (HWND)atoi(__argv[2]);

				GetClientRect(hFrameWnd, &rect);
				CreateWindow("ScreenSaverDraw", NULL,
					WS_CHILD | WS_VISIBLE,
					rect.left, rect.top,
					rect.right, rect.bottom,
					hFrameWnd, NULL,
					g_hInst, NULL);
				
				return 0;
			}
		//配置
		} else if (strchr(__argv[1], 'c')) {
			MessageBox(NULL, "此屏保程序暂不能进行配置",
				"Picure Screen Saver", MB_OK);
			// Preview mode
			return 0;
		}
	}	
	//-------------------proc start------- /s ----------//
	static TCHAR szAppName[] = TEXT("ScreenSaver");
	MSG          msg;
	WNDCLASS     wndclass;

	wndclass.style = CS_HREDRAW | CS_VREDRAW;
	wndclass.lpfnWndProc = WndProc;
	wndclass.cbClsExtra = 0;
	wndclass.cbWndExtra = 0;
	wndclass.hInstance = hInstance;
	wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
	wndclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
	wndclass.lpszMenuName = NULL;
	wndclass.lpszClassName = szAppName;

	if (!RegisterClass(&wndclass))
	{
		MessageBox(NULL, TEXT("This program requires Windows NT!"),
			szAppName, MB_ICONERROR);
		return 0;
	}

	g_hInst = hInstance;

	hwnd = CreateWindow(szAppName,  // window class name
		TEXT("MyScreenSaver"),		// window caption
		WS_POPUP|WS_VISIBLE,        // window style
		0,							// initial x position
		0,							// initial y position
		WS_MAXIMIZE,				// initial x size
		WS_MAXIMIZE,				// initial y size
		NULL,                       // parent window handle
		NULL,                       // window menu handle
		hInstance,                  // program instance handle
		NULL);						// creation parameters

	ShowWindow(hwnd, iCmdShow);
	UpdateWindow(hwnd);

	//定时器
	SetTimer(hwnd, TIMER_ID, TIM_LONG, timeProc);

	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	HDC         hdc, MemDC;
	PAINTSTRUCT ps;
	RECT        rect;
	HBITMAP OldBitmap;

	switch (message)
	{

		case WM_CREATE:
		{
			//得到用户名
			char username[256] = {0};
			DWORD dwnameLen = 256;
			GetUserNameA((LPSTR)username,&dwnameLen);
			//文件路径C:\Users\%USERNAME%\Pictures
			string pre("C:\\Users\\");
			pre += username;
			pre += "\\Pictures";
			File_Directory.assign(pre);


			int flag = 0;
			//获取路径下的所有.gif文件名
			flag += getFilesName(File_Directory, FileType_gif, FilesName);
			//获取路径下的所有.bmp文件名
			flag += getFilesName(File_Directory, FileType_bmp, FilesName);
			//获取路径下的所有.jpg文件名
			flag += getFilesName(File_Directory, FileType_jpg, FilesName);
			//获取路径下的所有.png文件名
			flag += getFilesName(File_Directory, FileType_png, FilesName);
			//获取路径下的所有.jpeg文件名
			flag += getFilesName(File_Directory, FileType_jpeg, FilesName);

			if (!flag) {
				MessageBox(hwnd, _T("没有可用的图片"), _T("出错啦..."), MB_OK);
				SendMessage(hwnd, WM_DESTROY, NULL, NULL);
			}

			//从磁盘载入第一张图片
			CImage cimg;
			cimg.Load(FilesName[index].c_str());

			//获得位图句柄
			g_hBitmapStruct.bmpFile = cimg.Detach();

			//准备第一张要显示的图片的参数
			BITMAP bmpInfo;
			GetObject((HGDIOBJ)g_hBitmapStruct.bmpFile, sizeof(bmpInfo), &bmpInfo);
			g_hBitmapStruct.bmpSize.x = bmpInfo.bmWidth;
			g_hBitmapStruct.bmpSize.y = bmpInfo.bmHeight;

			if (g_hBitmapStruct.bmpFile == NULL)
			{
				//MessageBox(NULL, TEXT("请尝试将图片添加到 C:\用户名\Pictures 下！\n仅支持bmp、jpg、png、jpeg格式"), TEXT("提示："), MB_OK);
				int i = GetLastError();
			}

			return 0;
		}

		case WM_PAINT:
		{
			if (g_hBitmapStruct.bmpFile == NULL)
				return 0;

			//获取设备环境句柄
			hdc = BeginPaint(hwnd, &ps);
			MemDC = CreateCompatibleDC(hdc);

			//准备显示图片
			GetClientRect(hwnd, &rect);
			OldBitmap = (HBITMAP)SelectObject(MemDC, g_hBitmapStruct.bmpFile);

			//显示图片
			TransparentBlt(hdc, 0, 0, cxn, cyn, MemDC, 0, 0, g_hBitmapStruct.bmpSize.x, g_hBitmapStruct.bmpSize.y, NULL);

			//还原设备
			SelectObject(MemDC, OldBitmap);
			//释放DC
			DeleteDC(MemDC);
			EndPaint(hwnd, &ps);

			return 0;
		}

		case WM_SIZE: {
			//重新获取屏幕尺寸
			cxn = GetSystemMetrics(SM_CXSCREEN);
			cyn = GetSystemMetrics(SM_CYSCREEN);
			//move windows
			MoveWindow(hwnd, 0, 0, cxn, cyn, true);

			break;
		}

		//隐藏光标
		case WM_SETCURSOR:
		{
			SetCursor(NULL);
			return FALSE;
		}

		case WM_LBUTTONDOWN:
		case WM_MBUTTONDOWN:
		case WM_RBUTTONDOWN:
		case WM_KEYDOWN:
		case WM_SYSKEYDOWN:
			PostQuitMessage(0); // 退出程序
			break;
		case WM_MOUSEMOVE:
		{
			INT nNew_X = LOWORD(lParam);
			INT nNew_Y = HIWORD(lParam);
			if (g_nOrigin_X == -1 && g_nOrigin_Y == -1)
			{
				g_nOrigin_X = nNew_X;
				g_nOrigin_Y = nNew_Y;
			}
			else if (g_nOrigin_X != nNew_X && g_nOrigin_Y != nNew_Y)
				PostQuitMessage(0);
			break;
		}

		case WM_ACTIVATE:
		case WM_ACTIVATEAPP:
		case WM_NCACTIVATE:
		{
			if (wParam == FALSE)
				PostQuitMessage(0);
			break;
		}


		//系统屏保消息或屏幕关闭时退出
		case WM_SYSCOMMAND:
		{
			if (wParam == SC_SCREENSAVE || wParam == SC_CLOSE)
				PostQuitMessage(0);
			break;
		}

		case WM_DESTROY:
		{
			KillTimer(NULL, TIMER_ID);
			FilesName.~vector();
			PostQuitMessage(0);
			return 0;
		}
	}

	return DefWindowProc(hwnd, message, wParam, lParam);
}

//定时器 循环加载图片，一次加载一张
void CALLBACK timeProc(HWND hWnd, UINT id, UINT_PTR paramx, DWORD paramy)
{
	index++;
	index %= FilesName.size();

	//从磁盘加载下一张图片
	CImage cimg;
	cimg.Load(FilesName[index].c_str());

	//获得位图句柄
	g_hBitmapStruct.bmpFile = cimg.Detach();

	//准备下一张要显示的图片的参数
	BITMAP bmpInfo;
	GetObject((HGDIOBJ)g_hBitmapStruct.bmpFile, sizeof(bmpInfo), &bmpInfo);
	g_hBitmapStruct.bmpSize.x = bmpInfo.bmWidth;
	g_hBitmapStruct.bmpSize.y = bmpInfo.bmHeight;

	InvalidateRect(hwnd, NULL, true);
	UpdateWindow(hwnd);
}


//获得目录下的目标图片名
int getFilesName(string &File_Directory, string &FileType, vector<string>&FilesName)
{
	string buffer = File_Directory + "\\*" + FileType;

	_finddata_t c_file;   // 存放文件名的结构体

	long hFile;
	hFile = _findfirst(buffer.c_str(), &c_file);   //找第一个文件名

	if (hFile == -1L) {   // 检查文件夹目录下存在需要查找的文件
		OutputDebugString("No ");
		OutputDebugString(FileType.c_str());
		OutputDebugString(" files in current directory!\n");
		return 0;
	} else {
		string fullFilePath;
		do{
			fullFilePath.clear();

			//路径+名字
			fullFilePath = File_Directory + "\\" + c_file.name;

			FilesName.push_back(fullFilePath);

		} while (_findnext(hFile, &c_file) == 0);  //如果找到下个文件的名字成功的话就返回0,否则返回-1  
		_findclose(hFile);

		return 1;
	}
}
